"""
xxxx电影数据可视化模块
功能：将爬取的电影数据生成静态图表和交互式图表
包括：评分前十柱状图、评分分布饼图、交互式HTML图表等
"""

import json
import logging
from pathlib import Path
from typing import Dict, Optional

import matplotlib

# 设置matplotlib使用非交互式后端，适合服务器环境
matplotlib.use("Agg")

import matplotlib.pyplot as plt

# 设置中文字体支持，解决中文显示问题
plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "Noto Sans CJK SC"]
# 解决负号显示问题
plt.rcParams["axes.unicode_minus"] = False

import pandas as pd

# 尝试导入pyecharts（可选依赖），用于生成交互式图表
try:
    from pyecharts import options as opts
    from pyecharts.charts import Bar, Page, Pie
except ImportError:  # pragma: no cover - optional dependency
    Bar = Pie = Page = None
    opts = None


logger = logging.getLogger(__name__)


def build_visualizations(
    df: pd.DataFrame,
    outputs: Dict[str, Path],
    base_url: Optional[str] = None,
) -> None:
        """
        因客户要求，该部分业务逻辑已折叠
        """


def _render_top10_bar(df: pd.DataFrame, output_path: Path) -> None:
    """
    生成评分前十电影的横向柱状图（静态图片）
    
    参数：
    - df: 电影数据DataFrame
    - output_path: 输出图片文件路径
    
    图表特点：
    - 横向条形图，便于显示长标题
    - 在条形末端显示具体评分数值
    - 使用醒目的颜色突出显示
    """
    # 筛选有评分的数据，按评分和投票数降序排列，取前10名
    top10 = (
        df.dropna(subset=["rating"])
        .sort_values(by=["rating", "votes"], ascending=[False, False])
        .head(10)
    )
    
    # 如果没有数据，跳过图表生成
    if top10.empty:
        logger.warning("Top10数据集为空；跳过柱状图生成。")
        return

    # 创建图形和坐标轴
    fig, ax = plt.subplots(figsize=(10, 6))
    # 绘制横向条形图，使用红色系颜色
    ax.barh(top10["title"], top10["rating"], color="#ff6f61")
    # Y轴反转，使评分最高的在顶部
    ax.invert_yaxis()
    ax.set_xlabel("评分")
    ax.set_title("评分最高的前10部电影")
    
    # 在每个条形末端添加评分文本
    for idx, (_, row) in enumerate(top10.iterrows()):
        ax.text(row["rating"] + 0.05, idx, f"{row['rating']:.1f}", va="center")
    
    # 调整布局并保存
    fig.tight_layout()
    fig.savefig(output_path, dpi=150)  # 150DPI保证图片清晰度
    plt.close(fig)  # 关闭图形释放内存
    logger.info("评分前十柱状图已保存至 %s", output_path)


def _render_rating_distribution(df: pd.DataFrame, output_path: Path) -> None:
    """
    生成评分分布饼图（静态图片）
    
    参数：
    - df: 电影数据DataFrame  
    - output_path: 输出图片文件路径
    
    评分区间划分：
    - 小于7.0分
    - 7.0-7.9分
    - 8.0-8.9分
    - 9.0分及以上
    """
    # 定义评分区间边界和标签
    bins = [0, 7.0, 8.0, 9.0, 10.0]
    labels = ["小于7.0", "7.0-7.9", "8.0-8.9", "9.0及以上"]
    
    # 将评分分配到各个区间
    df["rating_bucket"] = pd.cut(df["rating"], bins=bins, labels=labels, right=False)
    # 统计每个区间的电影数量，确保所有区间都有值
    distribution = df["rating_bucket"].value_counts().reindex(labels, fill_value=0)

    # 过滤掉数量为0的区间
    filtered = distribution[distribution > 0]
    if filtered.empty:
        logger.warning("没有评分数据；跳过饼图生成。")
        return

    # 创建饼图
    fig, ax = plt.subplots(figsize=(8, 6))
    ax.pie(
        filtered.values,
        labels=filtered.index,  # 区间标签
        autopct=lambda pct: f"{pct:.1f}%" if pct > 0 else "",  # 百分比显示，忽略0值
        startangle=140,  # 起始角度
        colors=["#8dd3c7", "#80b1d3", "#bebada", "#fb8072"],  # 配色方案
    )
    ax.set_title("不同评分区间的电影数量分布")
    fig.tight_layout()
    fig.savefig(output_path, dpi=150)
    plt.close(fig)
    logger.info("评分分布饼图已保存至 %s", output_path)


def _render_pyecharts_page(
    df: pd.DataFrame,
    output_path: Path,
    base_url: Optional[str] = None,
) -> None:
        """
        因客户要求，该部分业务逻辑已折叠
        """


def _persist_top10_snapshot(df: pd.DataFrame, output_path: Path) -> None:
    """
    保存评分前十的电影数据为JSON文件
    
    参数：
    - df: 电影数据DataFrame
    - output_path: 输出JSON文件路径
    
    用途：
    - 便于其他程序直接读取前10名数据
    - 轻量级的数据交换格式
    """
    # 获取评分前十的电影数据
    top10 = (
        df.dropna(subset=["rating"])
        .sort_values(by=["rating", "votes"], ascending=[False, False])
        .head(10)
        .to_dict(orient="records")  # 转换为字典列表格式
    )
    
    # 写入JSON文件
    output_path.write_text(
        json.dumps(top10, ensure_ascii=False, indent=2),  # 美化格式，支持中文
        encoding="utf-8",
    )
    logger.info("前十电影快照已保存至 %s", output_path)